﻿#region Copyright information
// 
// Copyright © 2005-2013 Yongkee Cho. All rights reserved.
// 
// This code is a part of the Biological Object Library and governed under the terms of the
// GNU Lesser General  Public License (LGPL) version 2.1 which accompanies this distribution.
// For more information on the LGPL, please visit http://bol.codeplex.com/license.
// 
// - Filename: Illinois.cs
// - Author: Yongkee Cho
// - Email: yongkeecho@gmail.com
// - Date Created: 2013-01-24 4:34 PM
// - Last Modified: 2013-01-25 3:59 PM
// 
#endregion
using System;

namespace BOL.Algorithms.Optimization
{
    /// <summary>
    /// Illinois method
    /// </summary>
    public sealed class Illinois : RootFinderByValueBase
    {
        #region Private variables

        private double _fMin;
        private double _fMax;
        private int _side;

        #endregion

        #region Constructor

        public Illinois(Func<double, double> function, int numberOfIterations = 100, double tolerance = 1e-10, bool isVerbose = true)
            : base(function, numberOfIterations, tolerance, isVerbose) { }

        #endregion

        #region RootFinderByValueBase overriden

        protected override void Expect(double min, double max)
        {
            _fMin = Function(min);
            _fMax = Function(max);
            _side = 0;

            Current = (_fMin * max - _fMax * min) / (_fMin - _fMax);
            Value = Function(Current.Value);
        }

        protected override void Maximize(ref double min, ref double max)
        {
            if (Math.Sign(Value) == Math.Sign(_fMax))
            {
                if (Current.HasValue)
                    max = Current.Value;
                _fMax = Value;
                if (_side == -1)
                    _fMin *= .5;
                _side = -1;
            }
            else
            {
                if (Current.HasValue)
                    min = Current.Value;
                _fMin = Value;
                if (_side == 1)
                    _fMax *= .5;
                _side = 1;
            }
        }

        #endregion
    }
}
